<?php

/**
 * Die abstrakte Basisklasse, von der alle Frontend XTensions
 * ableiten.
 *
 */
abstract class WSB_Xtension_Base
{

	/**
	 * Container
	 *
	 * @var Cms_Model_Container
	 */
	protected $_container;

	/**
	 * Modulinstanz
	 *
	 * @var Cms_Model_Xtension
	 */
	protected $_module;

	/**
	 * Request
	 *
	 * @var WSB_Xtension_Request
	 */
	protected $_request;

	/**
	 * REQUEST-Parameter die an die Modulinstanz uebergeben werden
	 *
	 * @var array
	 */
	protected $_params;

	/**
	 * View Objekt
	 *
	 * @var WSB_Xtension_View
	 */
	protected $_view;

	/**
	 * @var boolean
	 */
	protected $_noViewRenderer = false;

	/**
	 * Content
	 *
	 * @var string
	 */
	protected $_content;

	/**
	 * Translate Objekt
	 *
	 * @var Zend_Translate
	 */
	protected $_translate;

	/**
	 * @todo: Optimierung!!! Benoetigt jede Instanz eine View-Instanz?
	 */
	public function __construct()
	{
		// Request
		$this->_request = new WSB_Xtension_Request();

		// Parameter
	    $this->_params = array();
	}

	/**
	 * Die init-Methode wird unmittelbar vor dem Rendern aufgerufen.
	 *
	 * @return void
	 */
	public function init()
	{}

	/**
	 * Initializer fuer das Viewobjekt
	 *
	 */
	private function _initView()
	{
		if(empty($this->_noViewRenderer)) {
			$modulename = strtolower($this->_module->class);
			$xtensionPath = WSB_XTENSION_PATH . $modulename . '/';
			$relBasePath = str_replace(WSB_APP_PATH, '', $xtensionPath);
			$xtensionViewPath = $xtensionPath . 'views/';
			$altXtensionViewPath = WSB_PATH . 'design/' . $relBasePath . 'views/';
			$altXtensionViewPath2 = WSB_PATH . 'design/' . $relBasePath . $this->_module->id . '/views/';

			$this->_view = new WSB_Xtension_View();
			$this->_view->strictVars(true);
			$this->_view->addBasePath($xtensionViewPath);
			$this->_view->addBasePath($altXtensionViewPath);
			$this->_view->addBasePath($altXtensionViewPath2);

			// Standard Helferpfad
			$this->_view->addHelperPath(WSB_APP_PATH . 'library/WSB/View/Helper/', 'WSB_View_Helper');

			$this->_view->setConfig($this->getConfiguration());

		}
	}

	/**
	 * @see WSB_Xtension_Interface
	 * @return string
	 */
	public function render()
	{
		$controllers = $this->getModule()->getDescriptor()->getControllers();

		// Uebergabe ans Modul
	    $key = strtolower($this->_module->class);

	    if(array_key_exists($key, $_REQUEST)) {
	        $this->_params = $_REQUEST[$key];
	    } else {
	    	// Parameteruebergabe an Controller
			foreach($controllers AS $index=>$controller) {
				if($controller['class'] == get_class($this)) {
					$ctrlKey = $key.':'.$controller['key'];
					if(array_key_exists($ctrlKey, $_REQUEST)) {
		        		$this->_params = $_REQUEST[$ctrlKey];
		        		break;
					}
					$ctrlKey = $key.'_'.$controller['key'];
					if(array_key_exists($ctrlKey, $_REQUEST)) {
		        		$this->_params = $_REQUEST[$ctrlKey];
		        		break;
					}
				}
			}
	    }

	    $this->init();

		$action = $this->getParam('action', 'index');
		$action .= 'Action';
		if(method_exists($this, $action)) {
			$this->preAction();
			$this->$action();
			return $this->_content;
			$this->postAction();
		} else {
			$this->addPageNotFoundHeader();
			return sprintf('Error: Method "%s::%s()" does not exist.', get_class($this), $action);
		}

	}

	public function preAction() {}
	public function postAction() {}
	public function indexAction() {}

	/**
	 * @see WSB_Xtension_Interface
	 * @return string
	 */
	public function renderForBackend()
	{
		return $this->render();
	}

	/**
	 * @param string $content
	 * @return void
	 */
	public function addContent($content)
	{
		$this->_content .= $content;
	}

	/**
	 * @param string $html
	 * @param string $tag
	 * @return string
	 */
	public function wrapInBaseClass($html, $tag='div')
	{
		return sprintf('<%4$s class="%1$s %1$s-%2$d">%3$s</%4$s>', strtolower($this->getModule()->class), $this->getModuleId(), $html, $tag);
	}

	/**
	 * @return void
	 */
	public function clearContent()
	{
		$this->_content = '';
	}

	/**
	 * Request Objekt anfordern.
	 *
	 * @return WSB_Xtension_Request
	 */
	public function getRequest()
	{
		return $this->_request;
	}

	/**
	 * Alle Parameter.
	 *
	 * @return array
	 */
	public function getParams()
	{
	   return $this->_params;
	}

	/**
	 * Ein Parameter.
	 *
	 * @param string $key
	 * @param mixed $default
	 * @return mixed
	 */
	public function getParam($key, $default=null)
	{
	    if(array_key_exists($key, $this->_params)) {
	        return $this->_params[$key];
	    } else {
	        return $default;
	    }
	}

	/**
	 * Setter Methode fuer den Container
	 *
	 * @see WSB_Xtension_Interface
	 * @param Cms_Model_Container $container
	 */
	public function setContainer(Cms_Model_Container $container)
	{
		$this->_container = $container;
		// View initialisieren, nachdem setModule UND setContainer aufgerufen wurde
		if($this->_module instanceof Cms_Model_Xtension) {
			$this->_initView();
		}
	}

	/**
	 * Getter Methode fuer den Container
	 *
	 * @see WSB_Xtension_Interface
	 * @return Cms_Model_Container
	 */
	public function getContainer()
	{
		return $this->_container;
	}

	/**
	 * @return integer
	 */
	public function getPageId()
	{
		return $this->_container->page_id;
	}

	/**
	 * Konfigurations-Objekt zurueckgeben
	 *
	 * @return Zend_Config
	 */
	public function getConfiguration()
	{
		return $this->getModule()->getConfig();
	}

	/**
	 * Setter Methode fuer die Modulinstanz
	 *
	 * @see WSB_Xtension_Interface
	 * @param Cms_Model_Xtension $module
	 */
	public function setModule(Cms_Model_Xtension $module)
	{
		$this->_module = $module;
		// View initialisieren, nachdem setModule UND setContainer aufgerufen wurde
		if($this->_container instanceof Cms_Model_Container) {
			$this->_initView();
		}
	}

	/**
	 * Getter Methode fuer die Modulinstanz
	 *
	 * @see WSB_Xtension_Interface
	 * @return Cms_Model_Xtension
	 */
	public function getModule()
	{
		return $this->_module;
	}

	/**
	 * Name der Modulinstanz
	 *
	 * @return string
	 */
	public function getModuleName()
	{
		return $this->_module->name;
	}

	/**
	 * Gibt die ID der Modulinstanz zurueck
	 *
	 * @return integer
	 */
	public function getModuleId()
	{
		return intval($this->_container->instance_id);
	}

	/**
	 * @return boolean
	 */
	public function isEditable()
	{
		if($this instanceof WSB_Xtension_Content) {
		    return true;
		}
		if($this instanceof WSB_Xtension_Extension) {
			return true;
		}
		return false;
	}

	/**
	 * @return WSB_Xtension_View
	 */
	public function getView()
	{
		return $this->_view;
	}

	/**
	 * @return array
	 */
	public function getViewScriptPaths()
	{
		if(empty($this->_module) || empty($this->_container)) {
			throw new Exeption('WSB_Xtension_Base: Object not initialized (module or container not set)');
		}
		return empty($this->_noViewRenderer) ? $this->_view->getScriptPaths() : array();
	}

	/**
	 * @return void
	 */
	public function initTranslate()
	{
    	// --> Dies ist derselbe Code wie in WSB_Xtension_View::translate()
    	if(is_null($this->_translate)) {
			$this->_translate = Zend_Registry::get('Zend_Translate');
			$locale = Zend_Registry::get('Zend_Locale');
			// Erstes vorhandenes Uebersetzungsfile einbinden
			foreach($this->_view->getScriptPaths() AS $scriptPath) {
				$scriptPath = preg_replace('#views/scripts/$#', '', $scriptPath); // Neue Version
				$scriptPath = preg_replace('#views/$#', '', $scriptPath); // Alte Version
				$scriptPath .= 'etc/frontend.' . $locale.'.csv';
	        	if(is_file($scriptPath)) {
					$this->_translate->addTranslation($scriptPath, $locale);
					break;
	        	}
			}
    	}
		// <--
	}

	/**
	 * @param string $string
	 * @return string
	 */
    public function translate($string)
	{
		$this->initTranslate();
		return $this->_translate->_($string);
    }

    /**
     * @return string
     */
    public function getStylesheet()
	{
    	// Styles (Datenbank)
		$stylesheet = trim($this->_module->stylesheet);
		// Styles (Filesystem)
        foreach($this->getViewScriptPaths() AS $scriptPath) {
        	$scriptPath .= 'stylesheet.css';
        	if(is_readable($scriptPath)) {
        		$stylesheet = file_get_contents($scriptPath);
        		break;
        	}
        }
		return trim($stylesheet);
    }

    /**
     * @return string
     */
    public function getJavascript()
	{
    	// Javascript (Datenbank)
		$javascript = trim($this->_module->javascript);
		// Javascript (Filesystem)
        foreach($this->getViewScriptPaths() AS $scriptPath) {
        	$scriptPath .= 'javascript.js';
        	if(is_readable($scriptPath)) {
        		$javascript = file_get_contents($scriptPath);
        		break;
        	}
        }
		return trim($javascript);
    }

    /**
     * @return integer
     */
    public function getLanguageId()
    {
    	return intval(WSB_Frontend::getInstance()->getLanguageId());
    }

    /**
     * @param string $url
     * @param boolean $exit
     */
    public function redirect($url, $exit = true)
    {
		header('Location: ' . $url);
		if($exit) {
			exit;
		}
    }

    /**
     * @param integer $id
     * @param array $params
     * @param string $anchor
     * @param boolean $exit
     */
    public function redirectToPage($id, array $params=array(), $anchor='', $exit = true)
    {
    	$id = intval($id);
    	if($id > 0) {
	    	$url = WSB_Xtension_Url::getInstance()->getHrefToPage($id, $params, $anchor);
	    	$this->redirect($url, $exit);
    	}
    }

    /**
     * @param string $name
     * @return void
     */
    public function renderView($name)
    {
    	$this->_content .= $this->_view->render($name);
    }

    /**
     * @see Zend_View_Abstract::assign()
     * @param  string|array $spec
     * @param  mixed (Optional) $value
     * @return void
     */
    public function assignToView($spec, $value = null)
    {
    	$this->_view->assign($spec, $value);
    }

    /**
     * @return void
     */
    public function addPageNotFoundHeader()
    {
		header("HTTP/1.0 404 Not Found");
    }

}
